package org.jeecg.modules.student.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.system.vo.SysTenantVo;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.mybatis.TenantContext;
import org.jeecg.modules.classes.entity.CouClass;
import org.jeecg.modules.classes.service.ICouClassService;
import org.jeecg.modules.common.baseentity.BaseApiEntity;
import org.jeecg.modules.common.utils.DateUtil;
import org.jeecg.modules.grade.entity.CouGrade;
import org.jeecg.modules.grade.service.ICouGradeService;
import org.jeecg.modules.grade.service.impl.CouGradeServiceImpl;
import org.jeecg.modules.relation.relclassstudent.entity.RelClassStudent;
import org.jeecg.modules.relation.relclassstudent.service.IRelClassStudentService;
import org.jeecg.modules.student.entity.StuStudent;
import org.jeecg.modules.student.entity.StuStudentDemo;
import org.jeecg.modules.student.mapper.StuStudentMapper;
import org.jeecg.modules.student.service.IStuStudentService;
import org.jeecg.modules.student.vo.StuStudentVo;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * @Description: stu_student
 * @author: baochangrong
 * @Date: 2022-02-10
 * @Version: V1.0
 */
@Service
public class StuStudentServiceImpl extends ServiceImpl<StuStudentMapper, StuStudent> implements IStuStudentService {

    @Autowired
    private StuStudentMapper stuStudentMapper;
    @Autowired
    private ISysBaseAPI sysBaseAPI;
    @Autowired
    private ICouGradeService couGradeServiceImpl;
    @Autowired
    private ICouClassService couClassServiceImpl;
    @Autowired
    private IRelClassStudentService relClassStudentServiceImpl;
    @Value("${jeecg.path.upload}")
    private String upLoadPath;

    @Override
    public List<StuStudent> noClassStudentsList(String tenantId) {
        return stuStudentMapper.noClassStudentsList(tenantId);
    }

    @Override
    public List<StuStudent> classStudentQueryAll(String tenantId) {
        List<StuStudent> stuStudentList = stuStudentMapper.classStudentQueryAll(tenantId);
        return stuStudentList;
    }

    /**
     * 年级班级学生列表查询
     */
    @Override
    public IPage<StuStudentVo> gradeclassStudentListQueryAll(Page<StuStudentVo> page, String tenantId) {
        List<StuStudentVo> stuStudentVoList = stuStudentMapper.gradeclassStudentListQueryAll(page, tenantId);
        return page.setRecords(stuStudentVoList);
    }

    @Override
    public IPage<StuStudentVo> queryStuStudentVoLists(Page<StuStudentVo> page, @Param("queryParam") Map<String, String> queryParam, @Param("stuStudentVo") StuStudentVo stuStudentVo) {
        List<StuStudentVo> stuStudentVoList = stuStudentMapper.queryStuStudentVoLists(queryParam, stuStudentVo);
        return page.setRecords(stuStudentVoList);
    }

    @Override
    public Result<List<Map>> listBatchNumber(@Param("stuStudentVo") StuStudentVo stuStudentVo) {
        List<Map> stuStudentVoList = stuStudentMapper.listBatchNumber(stuStudentVo);
        return Result.OK(stuStudentVoList);
    }

    @Override
    public StuStudent getStuStudentByUserId(String userId) {
        return stuStudentMapper.getStuStudentByUserId(userId);
    }

    @Override
    public boolean createUserByStudentIds(String tenantId, String password, String ids, LoginUser loginUser, boolean force) {
        if (oConvertUtils.isEmpty(ids)) {
            return false;
        }
//        Collection<StuStudent> idList2 = idList;
//        List studentList = listByIds(idList);
        List idsli = Arrays.asList(ids.split(","));

        List<StuStudent> studentList = getStudentListByIds(ids);
        List<StuStudent> studentList2 = listByIds(idsli);
        SysTenantVo sysTenantVo = sysBaseAPI.getSysTenant(tenantId);


        //复制当前登录用户
        String oldUserJSON = JSONObject.toJSONString(loginUser);
        LoginUser newUser = JSONObject.parseObject(oldUserJSON, LoginUser.class);
        for (StuStudent stuStudent : studentList) {
            //是否强制执行创建用户（已有用户，重新创建新用户）
            if (force) {
                stuStudent.setUserId(null);
            }
            //判断是否为空，为空则执行，避免重复执行
            if (oConvertUtils.isEmpty(stuStudent.getUserId())) {
                if (oConvertUtils.isNotEmpty(stuStudent.getStudentNo())) {
                    newUser.setUsername(sysTenantVo.getPreCode() + stuStudent.getStudentNo()); //优先使用租户后缀+学号
                } else if (oConvertUtils.isNotEmpty(stuStudent.getStudentIdCardNo())) {
                    newUser.setUsername(stuStudent.getStudentNo()); //其次使用身份证号
                } else {
                    newUser.setUsername(sysTenantVo.getPreCode() + stuStudent.getStudentName()); //其次使用租户后缀+姓名
                }
                newUser.setPassword(password);
                newUser.setUserIdentity(4);//身份(字典码user_identity)：3老师 4学生  5家长 1.用户 2部门负责人 6虚拟班级
                newUser.setId(null);

                newUser.setRealname(stuStudent.getStudentName()); //工号：租户+学号
                newUser.setWorkNo(sysTenantVo.getPreCode() + stuStudent.getStudentNo());
                newUser.setBirthday(stuStudent.getStudentDateBirth());
                newUser.setOrgCode(stuStudent.getSysOrgCode());
                newUser.setSex(stuStudent.getStudentGender());
                newUser.setPhone(stuStudent.getStudentTelephone());
                newUser.setStatus(1); //正常，未冻结
                newUser.setDelFlag(0); //正常未删除
                newUser.setTelephone(stuStudent.getStudentTelephone());
                newUser.setEmail(stuStudent.getStudentEmail());
                newUser.setDepartIds(sysBaseAPI.getDepartIdsByOrgCode(stuStudent.getSysOrgCode())); //部门编码设置部门id

//                String newuserId = sysBaseAPI.addUser(tenantId,newUser);
                sysBaseAPI.addUser(tenantId, newUser);

                //更新学生的用户id
                stuStudent.setUserId(newUser.getId());
                updateById(stuStudent);
            }
        }
        //全部执行成功
        return true;
    }

    @Override
    public List<StuStudent> getStudentListByIds(String ids) {
        return stuStudentMapper.getStudentListByIds(ids);
    }

    /**
     * 导出excel
     *
     * @param request
     */
    public ModelAndView exportXlsDemo(HttpServletRequest request, StuStudentDemo object, String title, String secondTitle, ISysBaseAPI sysBaseAPI, JSONObject DictList) {
        // Step.1 组装查询条件
        //LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        StringBuffer text = new StringBuffer();

        // Step.3 说明部分
        DictList.forEach((key, value) -> {
            List<DictModel> dictModelList = null;
            List<CouGrade> gradeList = null;
            text.append(key + ": ");

            if ("gradeId".equals(value)) {
                QueryWrapper queryWrapperGrade = new QueryWrapper();
                queryWrapperGrade.eq("tenant_id", TenantContext.getTenant());
                queryWrapperGrade.orderByAsc("grade_order");
                gradeList = couGradeServiceImpl.list(queryWrapperGrade);
                for (CouGrade CouGradeOne : gradeList) {
                    text.append(CouGradeOne.getGradeName() + ":" + CouGradeOne.getId() + ";");
                }
                object.setGradeId(gradeList.get(0).getId());
            } else {
                dictModelList = sysBaseAPI.getDictItems(value.toString());
                for (DictModel dictModel : dictModelList) {
                    text.append(dictModel.getText() + ":" + dictModel.getValue() + ";");
                }
            }
            text.append("\n");
        });
        String secondTitleNew = secondTitle + "\n" + text.toString();

        List<StuStudentDemo> exportList = new ArrayList<>();
        exportList.add(object);


        // Step.3 AutoPoi 导出Excel
        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
        // Step.3  正文
        ExportParams exportParams = new ExportParams(title + "模板", secondTitleNew, title);
        exportParams.setType(ExcelType.XSSF);
        exportParams.setImageBasePath(upLoadPath);
        exportParams.setSecondTitleHeight(new Short("10"));
        //map.put("title",exportParams);//表格Title
        mv.addObject(NormalExcelConstants.PARAMS, exportParams);//表格Title
        mv.addObject(NormalExcelConstants.CLASS, StuStudentDemo.class);//表格对应实体
        mv.addObject(NormalExcelConstants.DATA_LIST, exportList);//数据集合
        return mv;
    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @Transactional
    public Result<?> importExcelDemo(HttpServletRequest request, HttpServletResponse response, IStuStudentService stuStudentService, BaseApiEntity baseApiEntity) {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
        for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
            MultipartFile file = entity.getValue();// 获取上传文件对象
            ImportParams params = new ImportParams();
            params.setTitleRows(2);
            params.setHeadRows(1);
            params.setNeedSave(true);
            String batchNumber = baseApiEntity.getUsername() + DateUtil.getNow("yyyyMMddHHmm");
            String classId = "";
            String studentId = "";
            long start = System.currentTimeMillis();
            try {
                List<StuStudent> list = ExcelImportUtil.importExcel(file.getInputStream(), StuStudent.class, params);
                //update-begin-author:taoyan date:20190528 for:批量插入数据
                for (StuStudent st : list) {
                    st.setSysOrgCode(baseApiEntity.getSysOrgCode());
                    st.setBatchNumber(batchNumber);
                    if(oConvertUtils.isEmpty(st.getStudentStatus()) ){
                        st.setStudentStatus(1)  ;
                    }
                    if ("".equals(st.getStudentName()) || null == st.getStudentName() ||
                            "".equals(st.getStudentIdCardNo()) || null == st.getStudentIdCardNo() ||
                            "".equals(st.getStudentEnrollmentYear()) || null == st.getStudentEnrollmentYear()) {
                        new IllegalArgumentException("文件中必填项有未填写的。" + st.toString() + "导入失败！请检查数据。");
                        return Result.error("文件中必填项有未填写的。" + st.toString() + "导入失败！请检查数据。");
                    }
                    QueryWrapper<CouGrade> queryWrapperGrandeOne = new QueryWrapper();
                    queryWrapperGrandeOne.eq("id", st.getGradeId());
                    queryWrapperGrandeOne.eq("tenant_id", TenantContext.getTenant());
                    CouGrade couGradeOne = couGradeServiceImpl.getOne(queryWrapperGrandeOne);
                    if (couGradeOne == null) {
                        new IllegalArgumentException("文件中年级编码填写不正确，系统中没有这样的年级。" + st.toString() + "导入失败！请检查数据。");
                        return Result.error("文件中年级编码填写不正确，系统中没有这样的年级。" + st.toString() + "导入失败！请检查数据。");
                    }
                    QueryWrapper<CouClass> queryWrapperClassOne = new QueryWrapper();
                    queryWrapperClassOne.eq("class_code", CouClass.ClassCode);
                    queryWrapperClassOne.eq("tenant_id", TenantContext.getTenant());
                    CouClass couClassOne = couClassServiceImpl.getOne(queryWrapperClassOne);
                    if (couClassOne == null) {
                        //雪花算法得到ID
                        classId = IdWorker.getIdStr();
                        CouClass classOne = new CouClass();
                        classOne.setClassCode(CouClass.ClassCode);
                        classOne.setId(classId);
                        classOne.setClassName(couGradeOne.getGradeName() + "(系統班)");
                        classOne.setGradeCode(couGradeOne.getId());
                        classOne.setClassOrder(666);
                        classOne.setClassNickname("系统虚拟班");
                        classOne.setClassRemark("导入数据时系统自动创建虚拟班，为 了挂载所属年级");
                        classOne.setClassIzOpen(1);
                        classOne.setClassIzDelete(0);
                        classOne.setClassStatus(1);
                        classOne.setClassStudentCapacity(CouClass.classStudentCapacityNum);
                        classOne.setClassTtype(4);
                        classOne.setClassStudentCount(0);
                        classOne.setTenantId(TenantContext.getTenant());
                        classOne.setSysOrgCode(baseApiEntity.getSysOrgCode());
                        classOne.setUserId(baseApiEntity.getLoginUser().getId());
                        classOne.setCreateTime(DateUtil.getCurrentDate());
                        if (!couClassServiceImpl.save(classOne)) {
                            new IllegalArgumentException("保存虚拟班级失败,请联系管理员，检查数据库");
                            return Result.error("保存虚拟班级失败,请联系管理员，检查数据库");
                        }
                    } else {
                        classId = couClassOne.getId();
                    }
                    studentId = IdWorker.getIdStr();
                    st.setId(studentId);

                    QueryWrapper queryWrapperRel = new QueryWrapper();
                    queryWrapperRel.eq("class_id", classId);
                    queryWrapperRel.eq("student_id", studentId);
                    queryWrapperRel.eq("class_student_status", 1);
                    queryWrapperRel.eq("tenant_id", TenantContext.getTenant());
                    RelClassStudent relClassStudent = relClassStudentServiceImpl.getOne(queryWrapperRel);
                    if (relClassStudent == null) {
                        RelClassStudent relClassStudentNew = new RelClassStudent();
                        relClassStudentNew.setClassStudentStatus(1);
                        relClassStudentNew.setClassId(classId);
                        relClassStudentNew.setStudentId(studentId);
                        relClassStudentNew.setCreateTime(DateUtil.getCurrentDate());
                        relClassStudentNew.setTenantId(TenantContext.getTenant());
                        if (!relClassStudentServiceImpl.save(relClassStudentNew)) {
                            new IllegalArgumentException("保存虚拟班级与学生关系失败，请联系管理员检查数据库");
                            return Result.error("保存虚拟班级与学生关系失败，请联系管理员检查数据库");
                        }
                    }

                }
                stuStudentService.saveBatch(list);
                //400条 saveBatch消耗时间1592毫秒  循环插入消耗时间1947毫秒
                //1200条  saveBatch消耗时间3687毫秒 循环插入消耗时间5212毫秒
                log.debug("消耗时间" + (System.currentTimeMillis() - start) + "毫秒");
                //update-end-author:taoyan date:20190528 for:批量插入数据
                return Result.ok("文件导入成功！数据行数：" + list.size());
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                return Result.error("文件导入失败:" + e.getMessage());
            } finally {
                try {
                    file.getInputStream().close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return Result.error("文件导入失败！");
    }
}
